/*
 * @Description: 创建分组计划弹窗
 * @Author: Rfan
 * @Date: 2022-06-28 20:35:00
 * @LastEditTime: 2022-09-08 14:50:28
 */

import { Key, useCallback, useEffect, useState } from 'react';
import { Button, Form, Input, message, Modal, Radio, Transfer, Typography } from 'antd';
import update from 'immutability-helper';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import TransferSelectItem from './components/TransferSelectItem';
import { jsonClone } from '@/utils';
import { fetchMetadata } from '@/api/metadata';
import { addGroupPlan } from '@/api/floderTree';
import { fetchATById } from '@/api/archivesType';
import { useFolderTreeContext } from '../../../contexts/FolderTreeContext';
import { QUERY_METADATA_ALL } from '@/view/system/Metadata/constants';
import { findTargetNodeByType } from '@/components/FolderTree';
import type { FC } from 'react';
import type { IFolderTreeNode } from '@/interfaces/folderTree';
import type { IArchiveType } from '@/interfaces/archiveType';
import type { IMetadata } from '@/interfaces/metadata';
import type { ICommonDialog } from '@/interfaces/global';

const { Paragraph, Text } = Typography;

interface CreateGroupPlanDialogProps extends ICommonDialog {
  node: IFolderTreeNode;
}

const CreateGroupPlanDialog: FC<CreateGroupPlanDialogProps> = (props) => {
  const { visible, node, onClose } = props;
  const { flatTreeList, groupTargetList, setGroupPlanList } = useFolderTreeContext();
  const [form] = Form.useForm();

  // 元数据列表
  const [fieldList, setFieldList] = useState<IMetadata[]>([]);
  // 已选择字段列表
  const [selectFieldList] = useState([]);
  // 穿梭框选中的项目key集合（穿梭框右侧）
  const [targetKeys, setTargetKeys] = useState<string[]>([]);
  // 选中项目的key集合
  const [selectedKeys, setSelectedKeys] = useState([]);
  // 保存按钮是否可点击标志
  const [, setSaveFlag] = useState<boolean>(false);

  // 保存按钮是否可点击标志
  const [level, setLevel] = useState(0);

  useEffect(() => {
    if (visible) {
      const atNode = findTargetNodeByType(node, 3, flatTreeList);
      let at: IArchiveType = atNode.appContext as unknown as IArchiveType;
      fetchATById(atNode.businessId).then((res: any) => {
        const { data } = res;
        at = data;
        /** 删除请求时保留      */
        if (at?.atCode) {
          const { atType, atCode, atLevel } = at;
          setLevel(atLevel);
          const fieldQuery = {
            metadataFieldType: QUERY_METADATA_ALL,
            coordinate: {
              atType,
              atCode,
              level: atLevel
            }
          };
          fetchMetadata(fieldQuery).then((resolve) => {
            setFieldList(resolve.data.map((item: IMetadata) => ({ ...item, key: item.id })));
          });
        }
        /** 删除请求时保留 END */
      });
    }
  }, [visible]);

  /**
   * @description: 关闭弹窗方法
   */
  const onCancel = () => {
    onClose();
  };

  /**
   * @description: 提交表单方法
   * @param {*} vals 表单数据
   */
  const onFinish = (vals: any) => {
    const ruleList = groupTargetList.map((item: any, idx: number) => ({
      configRule: item.configRule || false,
      dict_type_id: item.dict_type_id,
      // sortNo: idx,
      field_name: item.field_name,
      ruleConfig: item.ruleConfig,
      level
    }));
    const query = jsonClone(vals);
    query.ruleList = ruleList;
    query.nodeId = node.id;
    addGroupPlan(query).then((res) => {
      const { data } = res;
      message.success('添加分组方案成功');
      onClose(data);
    });
  };

  /**
   * @description: 选项在两栏之间转移时的回调函数,direction='right'时为增加，direction='left'时为删除
   * @param {any} nextTargetKeys 右侧框的key集合
   * @param {any} direction 数据移动方向
   * @param {any} moveKeys 移动的项目的key
   */
  const transferChange = (nextTargetKeys: any) => {
    setSaveFlag(true);
    setTargetKeys(nextTargetKeys);
    setGroupPlanList(
      nextTargetKeys.reverse().map((key: Key) => {
        const fieldItem = fieldList.find((item) => item.id === key) || {};
        const listItem = selectFieldList.find((lItem: any) => lItem.fieldId === key) || {};
        return { ...fieldItem, ...listItem };
      })
    );
    if (nextTargetKeys.length > 0) {
      setSaveFlag(true);
    } else {
      setSaveFlag(false);
    }
  };

  /**
   * @description: 选中项发生改变时的回调函数，用于项目选中的展示，设置为 单选
   * @param {function} sourceSelectedKeys 左侧选中
   * @param {function} targetSelectedKeys 右侧选中
   */
  const onSelectChange = (sourceSelectedKeys: Key[], targetSelectedKeys: Key[]) => {
    setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
  };

  /**
   * @description: 拖拽选中的条目触发，在此更新list
   */
  const moveSelect = useCallback((dragIndex: number, hoverIndex: number) => {
    console.log('moveSelect', dragIndex, hoverIndex);
    setGroupPlanList((state: any) =>
      update(state, {
        $splice: [
          [dragIndex, 1],
          [hoverIndex, 0, state[dragIndex]]
        ]
      })
    );
  }, []);

  /**
   * @description: 生成可拖拽列表
   */
  const renderSelect = useCallback(
    (selectItem: any, listProps: any, index: number, onChangea: any) => {
      return (
        <TransferSelectItem
          {...listProps}
          key={selectItem.key}
          index={index}
          item={selectItem}
          onChange={onChangea}
          moveSelect={moveSelect}
        />
      );
    },
    []
  );

  return (
    <Modal
      title="设置分组条件"
      visible={visible}
      width={600}
      destroyOnClose
      onCancel={onCancel}
      footer={[
        <Button key="close" onClick={onCancel}>
          关闭
        </Button>,
        <Button
          key="save"
          type="primary"
          onClick={() => {
            form.submit();
          }}
        >
          保存
        </Button>
      ]}
    >
      <Paragraph>
        选择档案库中<Text strong>字段名称</Text>，点击箭头设置为分组字段，系统将动态产生分类。
      </Paragraph>
      <Form
        labelCol={{ span: 5 }}
        wrapperCol={{ span: 18 }}
        preserve={false}
        form={form}
        onFinish={onFinish}
      >
        <Form.Item
          name="ruleName"
          label="分组方案名称"
          rules={[{ required: true, message: '请输入分组方案名称' }]}
        >
          <Input />
        </Form.Item>
        <Form.Item label="分组设置">
          <Radio.Group>
            <Radio value={1}>全部字段</Radio>
            <Radio value={2}>档号相关字段</Radio>
          </Radio.Group>
        </Form.Item>

        <Form.Item labelCol={{ span: 1 }} wrapperCol={{ span: 22 }} label=" " colon={false}>
          <Transfer
            dataSource={fieldList}
            titles={['待选分组字段', '已选分组字段']}
            listStyle={{
              width: '50%',
              height: 320
            }}
            targetKeys={targetKeys}
            selectedKeys={selectedKeys}
            onChange={transferChange}
            onSelectChange={onSelectChange}
            render={(item: IMetadata) => ({ value: `${item.id}`, label: <>{item.field_desc}</> })}
            showSelectAll={false}
          >
            {(listProps) => {
              if (listProps.direction === 'right') {
                return (
                  <DndProvider backend={HTML5Backend}>
                    <div className="ant-transfer-list-content">
                      {groupTargetList.map((item: any, idx: number) =>
                        renderSelect(item, listProps, idx, setSaveFlag)
                      )}
                    </div>
                  </DndProvider>
                );
              }
              return null;
            }}
          </Transfer>
        </Form.Item>
      </Form>
    </Modal>
  );
};

export default CreateGroupPlanDialog;
